package com.eb.aspect;

import com.eb.annotation.AutoAnnouncement;
import com.eb.constant.ExpConstant;
import com.eb.context.BaseContext;
import com.eb.domain.Announcement;
import com.eb.domain.Experience;
import com.eb.domain.Innovation;
import com.eb.domain.User;
import com.eb.enumeration.OperationType;
import com.eb.mapper.*;
import com.eb.vo.LikeInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义切面，实现自动经验计算与修改
 */
@Aspect
@Slf4j
@Component
public class AutoCalculateExpAspect {

    @Autowired
    private IAnnouncementMapper announcementMapper;
    @Autowired
    private IUserMapper userMapper;
    @Autowired
    private IInnovationMapper innovationMapper;
    @Autowired
    private IExperienceMapper experienceMapper;

    /**
     * 切入点，对哪些类的哪些方法进行拦截
     */
    @Pointcut("execution(* com.eb.service.impl.*.*(..)) && @annotation(com.eb.annotation.AutoCalculateExp)")
    public void AutoExpPointCut(){}

    /**
     * 后置返回通知，自动进行经验计算与修改
     */
    @AfterReturning(pointcut = "AutoExpPointCut()",returning = "res")
    public void autoFill(JoinPoint joinPoint,Object res){
        log.info("开始进行经验计算");
        //1.获取业务操作类型
        //1-1 方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //1-2获取注解对象,操作类型
        AutoAnnouncement announcement = signature.getMethod().getAnnotation(AutoAnnouncement.class);
        OperationType type = announcement.value();
        //2.获取方法参数--实体对象
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0)
        {
            //没有参数，直接返回
            return;
        }
        Object entity = args[0];
        //3.根据对象数据计算经验，并写入数据库的用户表，再写入经验记录表
        if (type == OperationType.LOOK) {
            //如果浏览成功
            if ((boolean) res)
            {
                log.info("浏览，经验+"+ExpConstant.LOOK_EXP);
                //查到user的经验，并增加经验
                User user = userMapper.selectById(BaseContext.getCurrentId());
                //获取经验之后的经验
                Integer upExp = user.getExperience()+ ExpConstant.LOOK_EXP;
                //当前等级
                Integer nowLevel = user.getLevel();
                user.setExperience(upExp);
                //发送经验记录
                Experience experience = new Experience();
                experience.setCreateTime(LocalDateTime.now());
                experience.setUserId(BaseContext.getCurrentId());
                experience.setReason("浏览，经验+"+ExpConstant.LOOK_EXP);
                experience.setValue(ExpConstant.LOOK_EXP);
                experienceMapper.insert(experience);
                judgeLevel(upExp,nowLevel,user);
                userMapper.updateById(user);
            }else
                return;
        }else if (type == OperationType.LIKE)
        {
            LikeInfoVO likeInfoVO = (LikeInfoVO) res;
            if (likeInfoVO.getMsg().equals("点赞成功"))
            {
                log.info("点赞，经验+"+ExpConstant.LIKE_EXP);
                //查到user的经验，并增加经验
                User user = userMapper.selectById(BaseContext.getCurrentId());
                //获取经验之后的经验
                Integer upExp = user.getExperience()+ ExpConstant.LIKE_EXP;
                //当前等级
                Integer nowLevel = user.getLevel();
                user.setExperience(upExp);
                //发送经验记录
                Experience experience = new Experience();
                experience.setCreateTime(LocalDateTime.now());
                experience.setUserId(BaseContext.getCurrentId());
                experience.setReason("点赞，经验+"+ExpConstant.LIKE_EXP);
                experience.setValue(ExpConstant.LIKE_EXP);
                experienceMapper.insert(experience);
                judgeLevel(upExp,nowLevel,user);
                userMapper.updateById(user);
            }else
            {
                return;
            }

        } else if (type == OperationType.COMMENT) {
            if ((boolean) res)
            {
                log.info("评论，经验+"+ExpConstant.COMMENT_EXP);
                //查到user的经验，并增加经验
                User user = userMapper.selectById(BaseContext.getCurrentId());
                //获取经验之后的经验
                Integer upExp = user.getExperience()+ ExpConstant.COMMENT_EXP;
                //当前等级
                Integer nowLevel = user.getLevel();
                user.setExperience(upExp);
                //发送经验记录
                Experience experience = new Experience();
                experience.setCreateTime(LocalDateTime.now());
                experience.setUserId(BaseContext.getCurrentId());
                experience.setReason("评论，经验+"+ExpConstant.COMMENT_EXP);
                experience.setValue(ExpConstant.COMMENT_EXP);
                experienceMapper.insert(experience);
                judgeLevel(upExp,nowLevel,user);
                userMapper.updateById(user);
            }else
                return;
        }else {
            if ((boolean) res) {
                log.info("收藏，经验+" + ExpConstant.PRESERVE_EXP);
                //查到user的经验，并增加经验
                User user = userMapper.selectById(BaseContext.getCurrentId());
                //获取经验之后的经验
                Integer upExp = user.getExperience() + ExpConstant.PRESERVE_EXP;
                //当前等级
                Integer nowLevel = user.getLevel();
                user.setExperience(upExp);
                //发送经验记录
                Experience experience = new Experience();
                experience.setCreateTime(LocalDateTime.now());
                experience.setUserId(BaseContext.getCurrentId());
                experience.setReason("收藏，经验+" + ExpConstant.PRESERVE_EXP);
                experience.setValue(ExpConstant.PRESERVE_EXP);
                experienceMapper.insert(experience);
                judgeLevel(upExp, nowLevel, user);
                userMapper.updateById(user);

            }

        }


    }

    public  void judgeLevel(Integer upExp,Integer nowLevel,User user)
    {

        //判断等级是否提升，如果提升，发送通知
        if (nowLevel != 7 && upExp >= ExpConstant.EXP_LEVEL[nowLevel])
        {
            nowLevel++;
            user.setLevel(nowLevel);
            //等级提升，更新用户等级
            userMapper.updateById(user);
            //向用户发送升级通知
            Announcement announcement = new Announcement();
            announcement.setUserId(user.getId());
            announcement.setCreateTime(LocalDateTime.now());
            announcement.setContent("恭喜你，等级提升到"+nowLevel+ExpConstant.LEVEL_NAME[nowLevel-1]);
            announcementMapper.insert(announcement);
        }

    }
}
